package cn.mengfly.testnrz.im.client.handler;

import cn.mengfly.testnrz.im.ProtoMsg;
import cn.mengfly.testnrz.im.client.ClientSession;
import cn.mengfly.testnrz.im.client.bean.User;
import cn.mengfly.testnrz.im.client.builder.HeartBeatMsgBuilder;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.concurrent.TimeUnit;

public class HeartBeatClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * 心跳时间间隔
     */
    private static final int HEARTBEAT_INTERVAL = 100;

    /**
     * 在handler被加入到pipline的时候发送心跳数据
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        ClientSession session = ClientSession.getSession(ctx);
        User user = session.getUser();
        HeartBeatMsgBuilder builder = new HeartBeatMsgBuilder(user, session);
        ProtoMsg.Message message = builder.buildMsg();
        // 发送心跳
        heartBeat(ctx, message);
    }

    /**
     * 接收到心跳响应
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!(msg instanceof ProtoMsg.Message)) {
            super.channelRead(ctx, msg);
            return;
        }
        ProtoMsg.Message pkg = ((ProtoMsg.Message) msg);
        ProtoMsg.HeadType type = pkg.getType();
        if (type.equals(ProtoMsg.HeadType.KEEPALIVE_RESPONSE)) {
            System.out.println("收到服务器返回的心跳响应回复");
            return;
        }
        super.channelRead(ctx, msg);
    }

    private void heartBeat(final ChannelHandlerContext ctx, final ProtoMsg.Message message) {
        ctx.executor().schedule(new Runnable() {
            @Override
            public void run() {
                if (ctx.channel().isActive()) {
                    System.out.println("发送心跳连接");
                    ctx.writeAndFlush(message);

                    // 递归调用，发送笑一次心跳
                    heartBeat(ctx, message);
                }
            }
        }, HEARTBEAT_INTERVAL, TimeUnit.SECONDS);
    }
}
